/** 
 * This file is part of project URSA. More information on the project
 * can be found at URSA's repository at GitHub
 * 
 * http://https://github.com/andersondomingues/ursa
 *
 * Copyright (C) 2018 Anderson Domingues, <ti.andersondomingues@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. **/
#include <iostream>
#include <sstream>
#include <iomanip>

//model API
#include <TDmaNetif.h>
#include <TRouter.h>
#include <UMemory.h>

#include <Tile.h>

/** 
 * @brief Initialize internal entities and binds hardware wires
 * @param x X-coordinate of the tile in the NoC
 * @param y Y-coordinate of the tile in the NoC
 **/
Tile::Tile(uint32_t x, uint32_t y){
	
	//map id wire to memory (local storage)
	uint32_t id = (ORCA_NOC_WIDTH * y) + x;
	
	stringstream ss;
	ss << std::setw(3) << std::setfill('0') << id;
	
	_name = ss.str();
	
	_signal_id = new Signal<uint32_t>(MAGIC_TILE_ID, this->GetName() + ".id");
	_signal_id->Write(id);
	
	//peripherals	
	_router = new HermesRouter(this->GetName() + ".router", x, y);
}

/**
 * @brief Destructor: cleans up allocated memory 
 */
Tile::~Tile(){
	
	delete(_signal_id);
	
	//delete hardware modules
	delete(_router);

}

/*
	//setters
    void SetSignalStall(Signal<int8_t>*);
	void SetSignalIntr(Signal<int8_t>*);
	void SetSignalSendStatus(Signal<int8_t>*);
	void SetSignalRecvStatus(Signal<int8_t>*);
	void SetSignalProgAddr(Signal<int32_t>*);
	void SetSignalProgSize(Signal<int32_t>*);
	void SetSignalProgSend(Signal<int8_t>*);
	void SetSignalProgRecv(Signal<int8_t>*);
*/

/**
 * @brief Get current router of the PE
 * @return A pointer to the instance of router
 */
HermesRouter* Tile::GetRouter(){ 
	return _router; 
}


/**
 * @brief Get current tile name
 * @return The name of the tile
 */
std::string Tile::GetName(){
	return _name;
}

/**
 * @brief Get current signal for tile ID
 * @return A pointer to the instance of signal
 */
Signal<uint32_t>* Tile::GetSignalId(){ 
	return _signal_id; 
}


/************************************* SETTERS **************************************/
/**
 * @brief Set a name to this tile
 * @param name Name to be given to the tile. Please note that the name is autogenerated
 * in accordance to the structure of the tile, so updating the name of the tile may 
 * not reflect on the naming of internal structures (to fix)
 */
void Tile::SetName(std::string name){
	_name = name;
}
